package net.obxlabs.tweetpad.behaviour;

import java.util.*;
import net.nexttext.*;
import net.nexttext.property.*;

public class ReorderSiblings extends Reorder {
	public static final int OFFSET_X = 0;  // TODO consolidate this with Maker+Shuffle+Swap
	public static final String REORDER_KEY = "ReorderKey";
	
	private Map<TextObject, TextObject[]> orderedChildren;
	
	/**
	 * Builds a default ReorderSiblings.
	 */
	public ReorderSiblings() {
		super();
		initMap();
	}
	
	/**
	 * Builds a ReorderSiblings.
	 */
	public ReorderSiblings(long speed) {
		super(speed);
		initMap();
	}
	
	public void initMap() {
		orderedChildren = Collections.synchronizedMap(new HashMap<TextObject, TextObject[]>());
	}
	
	/**
     * Applies Reorder on the specified TextObject and its siblings
     * <p>Result is complete when all the siblings return to their origin. </p>
     */
    public ActionResult behave(TextObject to) {
    	ActionResult result = new ActionResult();
    	
    	TextObjectGroup parent = to.getParent();
    	if (parent == null) {
    		to.getBook().log("ReorderChildren only works if you have a parent!");
    		return result;
    	}
    	
    	// initialize the list and the positions if not already done
    	if (!orderedChildren.containsKey(parent)) {
    		orderedChildren.put(parent, buildOrderedArray(parent));
    	}
    	
    	for (TextObject child = parent.getLeftMostChild(); child != null; child = child.getRightSibling()) {
    		result.combine(super.behave(child));
    	}
		
    	if (result.complete) {
    		// disable the key, if it exists
		    BooleanProperty toKey = (BooleanProperty)to.getProperty(REORDER_KEY);
			if (toKey != null) {
				toKey.set(false);
			}
			
			// reset the shuffle location property
			NumberProperty shuffleLocProp;
			NumberProperty originalLocProp;
			for (TextObject child = parent.getLeftMostChild(); child != null; child = child.getRightSibling()) {
				shuffleLocProp = (NumberProperty)child.getProperty("ShuffleLocation");
				originalLocProp = (NumberProperty)child.getProperty("OriginalLocation");
				shuffleLocProp.set(originalLocProp.get());
	    	}
			
			// drop the list
			orderedChildren.remove(parent);
	    }
	    
	    return result;
    }
    
    public TextObject[] buildOrderedArray(TextObjectGroup tog) {
    	TextObject[] tempList = new TextObject[tog.getNumChildren()];
    	
    	// create an ordered list of the children
    	for (TextObject child = tog.getLeftMostChild(); child != null; child = child.getRightSibling()) {
    		int loc = (int)((NumberProperty)child.getProperty("OriginalLocation")).get();
    		tempList[loc-1] = child;
    	}
    	
    	// calculate the reorder position for each child
    	Vector3Property currTargetPos;
    	double currX = 0;
    	double y = tempList[0].getPosition().get().y;
    	for (int i=0; i < tempList.length; i++) {
    		try {
    			currTargetPos = (Vector3Property)tempList[i].getProperty("TargetReorderPosition");
    			if (currTargetPos == null) {
        			tempList[i].init("TargetReorderPosition", new Vector3Property(new Vector3(currX, y)));
        		} else {
        			currTargetPos.set(new Vector3(currX, y));
        		}
        		currX += tempList[i].getBounds().width+OFFSET_X;
    		} catch (NullPointerException e) {
    			// XXX some null shit at the end of the tree, don't ask me why
    			System.out.println("ReorderSiblings: tempList["+i+"] is null...");
    			continue;
    		}
    	}
    	
    	return tempList;
    }
}
